#! /usr/bin/env python
"""
KIEL data format

This module offers functions to read NM64 BIN data as used in KIEL
and return data in the format as used by NMDB.

Copyright (C) 2010-2013 Christian T. Steigies <steigies@physik.uni-kiel.de>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

import os
import sys
import datetime
#import MySQLdb # python-mysqldb

#http://docs.python.org/library/sqlite3.html
# SpaceWx uses CentOS5 with Python2.4 and pysqlite2
try:
    from pysqlite2 import dbapi2 as sqlite3
except ImportError:
    try:
        from sqlite3 import dbapi2 as sqlite3
    except ImportError:
        print "SQLite module not found"
        sys.exit(1)

#from tools.datetool import str2datetime
from nmdb.nm64.nm64_data import NM64Data, row2insert

## --------------------------------------------------------------------------
def read_bin(filename):
    # read BIN file into chunk
    
    if os.path.exists(filename):
        binsize = os.stat(filename).st_size
        if (binsize) == 3120:
            print "opening %s" % (filename)
            binfile = open(filename, "rb")
            chunk = binfile.read(60*26*2) # 60 Minuten a 26 Worte a 2 byte
            binfile.close()
        else:
            print ("file %s is corrupt, size is %i bytes instead of 3120 bytes"
                   ) % (filename, binsize)
            sys.exit(1)
    else:
        print "file not found: %s" % (filename)
        sys.exit(1)

    return(chunk)


def bin2frame(chunk):
    # convert BIN data to frame

    # create a 60*26 array filled with zero
    frame = []
    for i in range (0, 60):
        frame.append([0]*26)

    for i in range(0, 60):
        for j in range(0, 26):
            idx = 26*2*i + 2*j
            word = ord(chunk[idx]) + 256*ord(chunk[idx+1])
            frame[i][j] = word

    return(frame)


def frame2bin(frame):
    # convert frame to BIN chunk

    chunk = ''
    for i in range(0, 60):
        for j in range(0, 26):
            word = frame[i][j]
            msb = int(word / 256)
            lsb = (word - 256*msb)
            #word2 = lsb+256*msb
            #print "%5i %3i %3i %5i" %(word, lb, hb, word2)

            chunk += chr(lsb)+chr(msb)

    return(chunk)


def print_frame(frame):
    # print out frame
    # determine if frame contains zeros -> shift_frame

    shift_frame = 0
    print "\nmin",
    for i in range(0, 18):
        print "zr#%02i " % (i+1),
    print "press  temp0  temp1   HV1    HV2    HV3  deltaT   hour"

    for i in range(0, 60):
        linesum = 0
        print "\n %02i" % (i), 
        for j in range(0, 26):
            print "%5i " % (frame[i][j]),
            linesum = linesum + frame[i][j]
        #c=0.0549254*(256*256*frame[i][25]+frame[i][24])
        #print c,
        #print "%02i:" %(c div 3600) # time in seconds
        if (linesum == 0):
            ## empty line found -> all data needs to be shifted to the end of the frame
            ## check if hour in last line = current_hour+1 ?
            print "NO DATA",
            if not(shift_frame):
                shift_frame = i

    print "\n"

    return(shift_frame)

## --------------------------------------------------------------------------
class Kiel(NM64Data):
    def __init__(self, station, year, month, day, hour):
        """read 1hour of BIN data for station kiel
        """

        NM64Data.__init__(self, station, year, month, day, hour)

        # get one hour of data
        filename = ("/data/kermes/NM64/%04i/bin/%02i%02i%02i%02i.bin"
                    ) % (year, year%100, month, day, hour)
        chunk = read_bin(filename)
        frame = bin2frame(chunk)

        # store data in internal sqlite database
        for i in range(0, 60):
            row = [self.dt(i)]
            for j in range(0, 26): # 18 channels, pressure, temp1, temp2, hv1, hv2, hv3, dt, hour: 26 values
                row.append(frame[i][j])
            #print row
            querystring = row2insert(row)
            #print "query", querystring
            self._c.execute(querystring)


    def _value(self, minute):
        """return values as read in"""
        
        dt = str(datetime.datetime(self._year, self._month, self._day, self._hour, minute, 0))
        cols = "ch01, ch02, ch03, ch04, ch05, ch06, ch07, ch08, ch09, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, pressure"
        querystring = ("SELECT %s FROM data WHERE datetime == \"%s\""
                       % (cols, dt))
        self._c.execute(querystring)
        row = self._c.fetchone() # should return only one line, or None
        #print "SQL:", row
        if row:
            return row
        else:
            return None

## --------------------------------------------------------------------------

if __name__ == "__main__":
    print "This is the NM64_BIN KIEL module for NMDB."

    station = "kiel"
    year = 2011
    month = 11
    day = 1
    hour = 0

    if 0:
        filename = ("/data/kermes/NM64/%04i/bin/%02i%02i%02i%02i.bin"
                    % (year, year%100, month, day, hour))


        chunk = read_bin(filename)
        frame = bin2frame(chunk)
        print_frame(frame)

    else:
        data = Kiel(station, year, month, day, hour)
